package com.vois.jack.btmgr.devices.WLBleOpusDevice;

import com.vois.jack.btmgr.classicbase.BtOpusCodedRecorder;
import com.vois.jack.btmgr.classicbase.BtRecorderInterface;
import com.vois.jack.btmgr.devices.WLCommonBleDev.DefaultWLBleMediaDevice;
import com.vois.jack.btmgr.devices.WLCommonBleDev.WLBleCommand;
import com.vois.jack.btmgr.util.Logger;

import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

public class WLBleOpusDevice extends DefaultWLBleMediaDevice {
    private Logger logger = Logger.getLogger(WLBleOpusDevice.class);
    private boolean isOpusSizeVariable;
    private int fixedOpusSize;
    private BtOpusCodedRecorder btOpusCodedRecorder;
    private Timer recordFeatureMonitorTimer;

    @Override
    public String getDeviceModel() {
        return "WLBleOpus Device";
    }

    @Override
    public void onScanStateChanged(int state) {

    }

    @Override
    public boolean hasRecorder() {
        return true;
    }

    @Override
    public BtRecorderInterface getRecorder(int recorderType) {
        if (recorderType == OPUS_RECORDER) {
            btOpusCodedRecorder = new BtOpusCodedRecorder();
            return btOpusCodedRecorder;
        }

        return null;
    }

    @Override
    public void onVerifying() {

    }

    private void sendRecordFeatureQuery() {
        sendCommand(WLBleCommand.BLE_CMD_QUERY_MEDIA_FEATURE, null, 0);
        recordFeatureMonitorTimer = new Timer();
        recordFeatureMonitorTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                sendRecordFeatureQuery();
            }
        }, 500);
    }

    @Override
    public void onReady() {
        super.onReady();
        logger.d("onReady BLE_CMD_QUERY_MEDIA_FEATURE");
        sendRecordFeatureQuery();
    }

    @Override
    public boolean onMediaFeatureRet(int cmdLen, byte[] cmdData) {
        boolean ret = super.onMediaFeatureRet(cmdLen, cmdData);
        if (recordFeatureMonitorTimer != null) {
            recordFeatureMonitorTimer.cancel();
            recordFeatureMonitorTimer = null;
        }
        logger.dumpArray(cmdData, cmdLen);
        if (supportMediaStreamType == OPUS_COMPO_PACK) {
            if (mediaParams[0] == 0x00) {
                isOpusSizeVariable = false;
                fixedOpusSize = mediaParams[1];
            } else {
                isOpusSizeVariable = true;
                fixedOpusSize = 0;
            }
        }

        return ret;
    }

    @Override
    protected void onStreamDataProcess(byte[] data) {
        int flag1 = data[0] & 0xFF;
        int flag2 = data[1] & 0xFF;
        int len = data[2] & 0xFF;

        logger.dumpArray(data, data.length);
        logger.d("supportMediaStreamType: " + supportMediaStreamType);
        logger.d("isOpusSizeVariable:" + isOpusSizeVariable);
        logger.d("btOpusCodedRecorder:" + btOpusCodedRecorder);
        logger.d("len:" + len);

        if (flag1 != 0xAA || flag2 != 0xBB) {
            return;
        }

        if (btOpusCodedRecorder != null) {
            if (supportMediaStreamType == OPUS_COMPO_PACK) {
                int currentProcessedLen = 3;
                if (isOpusSizeVariable) {
                    int opusSize;
                    while (currentProcessedLen < len + 3) {
                        opusSize = data[currentProcessedLen];
                        currentProcessedLen++;
                        btOpusCodedRecorder.putEncodedRecordData(data, currentProcessedLen, opusSize);
                        currentProcessedLen += opusSize;
                    }
                } else if (len % fixedOpusSize == 0) {
                    while (currentProcessedLen < len + 3) {
                        btOpusCodedRecorder.putEncodedRecordData(data, currentProcessedLen, fixedOpusSize);
                        currentProcessedLen += fixedOpusSize;
                    }
                }
            }else if (supportMediaStreamType == OPUS_SINGLE_PACK){
                btOpusCodedRecorder.putEncodedRecordData(data, 3, len);
            }
        }
    }

    @Override
    protected int getRequestMaxMtu() {
        return 256;
    }

    @Override
    public int getDefaultRecorderType() {
        return OPUS_RECORDER;
    }
}
